// src/store/slices/authSlice.ts
import {createAsyncThunk, createSlice, PayloadAction} from '@reduxjs/toolkit';
import authService from '../../services/authService';
import {User} from '../../types';

interface AuthState {
  user: User | null;
  token: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  isEmailVerified: boolean;
  lastLoginTime: string | null;

  isInitialized: boolean;
}

const initialState: AuthState = {
  user: null,
  token: null,
  refreshToken: null,
  isAuthenticated: false,
  isLoading: false,
  error: null,
  isEmailVerified: false,
  lastLoginTime: null,

  isInitialized: false,
};

// 异步actions
export const login = createAsyncThunk(
  'auth/user/login',
    async ({ email, password }: { email: string; password: string }, { rejectWithValue }) => {
      try {
        return await authService.login(email, password);
      } catch (error: any) {
        console.error('Login error:', error);
        return rejectWithValue(error?.response?.data?.message || error?.message || '登录失败');
      }
    }
);

export const register = createAsyncThunk(
  'auth/user/register',
    async (data: {
      email: string;
      username: string;
      password: string;
      verificationCode?: string;
    }, { rejectWithValue }) => {
      try {
        const response = await authService.register(data);
        return response;
      } catch (error: any) {
        console.error('Register error:', error);
        return rejectWithValue(error?.response?.data?.message || error?.message || '注册失败');
      }
    }
);

// 重置密码
export const resetPassword = createAsyncThunk(
    'auth/user/resetPassword',
    async ({ email, code, newPassword }: {
      email: string;
      code: string;
      newPassword: string;
    }, { rejectWithValue }) => {
      try {
        await authService.resetPassword(email, code, newPassword);
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '重置密码失败');
      }
    }
);

export const logout = createAsyncThunk(
    'auth/logout',
    async (_, { rejectWithValue }) => {
      try {
        await authService.logout();
      } catch (error: any) {
        console.error('Logout error:', error);
        // 即使登出失败，也要清除本地状态
        return rejectWithValue(error?.message || '登出失败');
      }
    }
);

export const updateProfile = createAsyncThunk(
    'auth/user/updateProfile',
    async (data: { username?: string; avatarUrl?: string }, { rejectWithValue }) => {
      try {
        const response = await authService.updateProfile(data);
        return response;
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '更新资料失败');
      }
    }
);

export const changePassword = createAsyncThunk(
    'auth/user/changePassword',
    async ({ oldPassword, newPassword }: {
      oldPassword: string;
      newPassword: string
    }, { rejectWithValue }) => {
      try {
        await authService.changePassword(oldPassword, newPassword);
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '修改密码失败');
      }
    }
);

export const refreshToken = createAsyncThunk(
    'auth/refreshToken',
    async (_, { rejectWithValue }) => {
      try {
        const token = await authService.refreshToken();
        return token;
      } catch (error: any) {
        return rejectWithValue(error?.message || '刷新token失败');
      }
    }
);

export const loadUserInfo = createAsyncThunk(
    'auth/loadUserInfo',
    async (_, { rejectWithValue }) => {
      try {
        const response = await authService.getUserInfo();
        return response;
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '获取用户信息失败');
      }
    }
);

// 发送注册验证码
export const sendRegisterCode = createAsyncThunk(
    'auth/user/sendRegisterCode',
    async (email: string, { rejectWithValue }) => {
      try {
        await authService.sendRegisterCode(email);
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '发送验证码失败');
      }
    }
);

// 发送密码重置验证码
export const sendResetCode = createAsyncThunk(
    'auth/user/sendResetCode',
    async (email: string, { rejectWithValue }) => {
      try {
        await authService.sendResetCode(email);
      } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || error?.message || '发送验证码失败');
      }
    }
);

// 初始化认证状态（从本地存储加载）
export const initializeAuth = createAsyncThunk(
    'auth/initialize',
    async (_, { rejectWithValue }) => {
      try {
        const authData = await authService.loadAuthData();
        return authData;
      } catch (error: any) {
        return rejectWithValue(error?.message || '初始化失败');
      }
    }
);


const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    setCredentials: (
        state,
        action: PayloadAction<{
          user: User;
          token: string;
          refreshToken?: string;
        }>
    ) => {
      state.user = action.payload.user;
      state.token = action.payload.token;
      state.refreshToken = action.payload.refreshToken || state.refreshToken;
      state.isAuthenticated = true;
      state.error = null;
    },
    updateUser: (state, action: PayloadAction<Partial<User>>) => {
      if (state.user) {
        state.user = { ...state.user, ...action.payload };
      }
    },
    clearError: (state) => {
      state.error = null;
    },
    setEmailVerified: (state, action: PayloadAction<boolean>) => {
      state.isEmailVerified = action.payload;
    },
    resetAuth: (state) => {
      // 保持初始化状态，只重置认证相关数据
      state.user = null;
      state.token = null;
      state.refreshToken = null;
      state.isAuthenticated = false;
      state.error = null;
      state.isEmailVerified = false;
      state.lastLoginTime = null;
      state.isLoading = false;
    },
  },
  extraReducers: (builder) => {
    builder
        // 🔥 Initialize
        .addCase(initializeAuth.fulfilled, (state, action) => {
          const { token, refreshToken, user } = action.payload;
          state.token = token;
          state.refreshToken = refreshToken;
          state.user = user;
          state.isAuthenticated = !!(token && user);
          state.isInitialized = true;
        })
        .addCase(initializeAuth.rejected, (state) => {
          state.isInitialized = true;
        })
        // Login
        .addCase(login.pending, (state) => {
          state.isLoading = true;
          state.error = null;
        })
        .addCase(login.fulfilled, (state, action) => {
          state.isLoading = false;
          state.isAuthenticated = true;
          state.user = action.payload.user;
          state.token = action.payload.token;
          state.refreshToken = action.payload.refreshToken;
          state.lastLoginTime = new Date().toISOString();
          state.error = null;
          state.isEmailVerified = action.payload.user?.emailVerified || false;
        })
        .addCase(login.rejected, (state, action) => {
          state.isLoading = false;
          state.error = action.payload as string || '登录失败';
          state.isAuthenticated = false;
        })
        // Register
        .addCase(register.pending, (state) => {
          state.isLoading = true;
          state.error = null;
        })
        .addCase(register.fulfilled, (state, action) => {
          state.isLoading = false;
          state.isAuthenticated = true;
          state.user = action.payload.user;
          state.token = action.payload.token;
          state.refreshToken = action.payload.refreshToken;
          state.lastLoginTime = new Date().toISOString();
          state.error = null;
          state.isEmailVerified = action.payload.user?.emailVerified || true;
        })
        .addCase(register.rejected, (state, action) => {
          state.isLoading = false;
          state.error = action.payload as string || '注册失败';
          state.isAuthenticated = false;
        })
        // Send Register Code
        .addCase(sendRegisterCode.rejected, (state, action) => {
          state.error = action.payload as string || '发送验证码失败';
        })
        // Send Reset Code
        .addCase(sendResetCode.rejected, (state, action) => {
          state.error = action.payload as string || '发送验证码失败';
        })
        // Reset Password
        .addCase(resetPassword.rejected, (state, action) => {
          state.error = action.payload as string || '重置密码失败';
        })
        // Logout
        .addCase(logout.fulfilled, (state) => {
          state.user = null;
          state.token = null;
          state.refreshToken = null;
          state.isAuthenticated = false;
          state.error = null;
          state.isEmailVerified = false;
          state.lastLoginTime = null;
          state.isLoading = false;
        })
        .addCase(logout.rejected, (state) => {
          // 即使登出失败，也清除本地状态
          state.user = null;
          state.token = null;
          state.refreshToken = null;
          state.isAuthenticated = false;
          state.error = null;
          state.isEmailVerified = false;
          state.lastLoginTime = null;
          state.isLoading = false;
        })
        // Update Profile
        .addCase(updateProfile.fulfilled, (state, action) => {
          state.user = action.payload;
        })
        .addCase(updateProfile.rejected, (state, action) => {
          state.error = action.payload as string || '更新资料失败';
        })
        // Change Password
        .addCase(changePassword.fulfilled, (state) => {
          // 修改密码后需要重新登录
          state.isAuthenticated = false;
          state.token = null;
          state.refreshToken = null;
        })
        .addCase(changePassword.rejected, (state, action) => {
          state.error = action.payload as string || '修改密码失败';
        })
        // Refresh Token
        .addCase(refreshToken.fulfilled, (state, action) => {
          state.token = action.payload;
        })
        .addCase(refreshToken.rejected, (state, action) => {
          state.error = action.payload as string || '刷新token失败';
          // token刷新失败，清除认证状态
          state.isAuthenticated = false;
          state.token = null;
          state.refreshToken = null;
        })
        // Load User Info
        .addCase(loadUserInfo.fulfilled, (state, action) => {
          state.user = action.payload;
        })
        .addCase(loadUserInfo.rejected, (state, action) => {
          state.error = action.payload as string || '获取用户信息失败';
        });
  },
});

export const {
  setCredentials,
  updateUser,
  clearError,
  setEmailVerified,
  resetAuth,
} = authSlice.actions;

export default authSlice.reducer;